/**
 * 过滤器组件
 * */
import React from "react";
import {ValidateStyleAdjustment} from "@/biz-components/claim-items/components-v2/cell-input";
import {CommonFilterItemProps, CommonFilterItemRender} from "@/biz-components/claim-items/components-v2";

export interface CommonFilterProps {
	// 过滤数据的一个方法，通过ref的方式传递给外层组件，外层组件可以调用这个方法根据当时过滤器输入的值过滤数据
	filterFunctionRef: React.MutableRefObject<((data: any[]) => any[]) | null>;

	/*
	 * 过滤器输入新的值的回调
	 * */
	onChange: () => void;

	/*
		元模型metas 用来获取label
	 * */
	metaArr: any[];

	// 获取当前的过滤条件对象
	getCurrentFilterObjectRef?: React.MutableRefObject<(() => {[name: string]: any}) | null>;

}

/**
 * 记录某一个筛选项当前的数据
 * */
interface FilterItemData {

	/**
	 * 这个筛选项名称
	 * */
	name: string;

	/**
	 * 这个筛选项的筛选方法
	 * */
	filterFunction: (filterValue: any, dataValue: any) => boolean;

	/**
	 * 获取这个筛选项组件当前的值的方法
	 * */
	getCurrentValue: (() => any) | null;
}

export class CommonFilter extends  React.Component<CommonFilterProps, {  }> {

	/**
	 * 记录当前渲染的所有筛选项
	 * */
	filterItems: Array<FilterItemData> = [];

	private addFilterItem(
		name: string,
		filterFunction: (filterValue: any, dataValue: any) => boolean,
		getFilterItemValue: () => any
	) {
		let index = this.filterItems.findIndex((item) => item.name === name);
		if(index !== -1) {
			this.filterItems[index] = {
				name,
				filterFunction,
				getCurrentValue: getFilterItemValue
			}
		} else {
			this.filterItems.push({
				name,
				filterFunction,
				getCurrentValue: getFilterItemValue
			})
		}
	}
	private removeFilterItem(name: string) {
		this.filterItems = this.filterItems.filter((item) => item.name !== name);
	}

	constructor(props: CommonFilterProps) {
		super(props);
		this.onFilterItemValueChange = this.onFilterItemValueChange.bind(this);
		this.filterData = this.filterData.bind(this);
		this.getFilterObject = this.getFilterObject.bind(this);
	}
	componentDidMount() {
		this.props.filterFunctionRef.current = this.filterData;
		if(this.props.getCurrentFilterObjectRef) {
			this.props.getCurrentFilterObjectRef.current = this.getFilterObject;
		}
	}
	componentWillUnmount() {
		this.props.filterFunctionRef.current = null;
		if(this.props.getCurrentFilterObjectRef) {
			this.props.getCurrentFilterObjectRef.current = null;
		}
	}
	componentDidUpdate(prevProps: Readonly<CommonFilterProps>, prevState: Readonly<{}>, snapshot?: any) {
		if(prevProps.filterFunctionRef !== this.props.filterFunctionRef) {
			prevProps.filterFunctionRef.current = null;
			this.props.filterFunctionRef.current = this.filterData;
		}
		if(prevProps.getCurrentFilterObjectRef !== this.props.getCurrentFilterObjectRef) {
			if(this.props.getCurrentFilterObjectRef) {
				this.props.getCurrentFilterObjectRef.current = null;
			}
		}
	}

	timeoutId: any;
	/**
	 * 某个过滤器的输入了新的值
	 * 一定的延迟之后触发props onChange 防止刷新频率过高
	 * */
	onFilterItemValueChange() {
		if(this.timeoutId) {
			clearTimeout(this.timeoutId);
		}
		this.timeoutId = setTimeout(() => {
			this.props.onChange();
		}, 300);
	}

	/**
	 * 获取当前的过滤条件对象
	 * */
	public getFilterObject() {
		let filterObj: {[name: string]: any} = {};
		for(const filterItem of this.filterItems) {
			if(filterItem.getCurrentValue) {
				filterObj[filterItem.name] = filterItem.getCurrentValue();
			}
		}
		return filterObj;
	}

	/**
	 * 外部组件调用这个方法过滤数据
	 * */
	public filterData(data: any[] = []): any[] {
		// 所有过滤项的值
		let filterObj: {[name: string]: any} = {};
		// 过滤项的过滤方法
		let filterFuncMap: {[name: string]: (filterData: any, data: any) => boolean} = {};
		for(const filterItem of this.filterItems) {
			if(filterItem.getCurrentValue) {
				filterObj[filterItem.name] = filterItem.getCurrentValue();
				filterFuncMap[filterItem.name] = filterItem.filterFunction;
			}
		}

		return data.filter((dataItem: object) => {
			let match = true;
			for(const key in filterObj) {
				if(filterFuncMap[key](filterObj[key], dataItem[key])) {

				} else {
					match = false;
					break;
				}
			}
			return match;
		});
	}

	render() {
		const {metaArr, children} = this.props;
		return (
			<ValidateStyleAdjustment invalid={false}>
				<div className={"claim-items-filter"}>
					{
						React.Children.map(children, (child) => {
							if(!child) return null;
							// @ts-ignore
							const childProps: CommonFilterItemProps<any> = child.props;

							return (
								<CommonFilterItemRender
									name={childProps.name}
									Component={childProps.Component}
									filterFunction={childProps.filterFunction}
									onFilterItemMount={(func) => {
										this.addFilterItem(childProps.name, childProps.filterFunction, func)
									}}
									onFilterItemUnMount={() => {
										this.removeFilterItem(childProps.name);
									}}
									metaArr={metaArr}
									onChange={this.onFilterItemValueChange}
									initialValue={childProps.initialValue}
								/>
							)
						})
					}
					<div className={"filter-item foo"}> </div>
					<div className={"filter-item foo"}> </div>
					<div className={"filter-item foo"}> </div>
				</div>
			</ValidateStyleAdjustment>
		);
	}
}
